package com.zeny.coding.controller.admin.system;

import com.alibaba.fastjson.JSON;

import com.zeny.coding.constants.CourseConstants;
import com.zeny.coding.dto.PageDto;
import com.zeny.coding.dto.Response;
import com.zeny.coding.dto.UserDto;
import com.zeny.coding.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.xml.bind.ValidationException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <h2>用户</h2>
 *
 * @Author Zeny
 */
@SuppressWarnings("all")
@RestController
@RequestMapping("/system/admin/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/list")
    public Response list(@RequestBody PageDto<UserDto> pageDto) {
        pageDto.check();
        userService.list(pageDto);
        return new Response().success().data(pageDto).message(CourseConstants.QUERY_SUCCESS);
    }

    @PostMapping("/save")
    public Response save(@RequestBody UserDto userDto) throws ValidationException {
        userDto.isValidForSave();
        this.userService.save(userDto);
        return new Response().success().message(CourseConstants.SAVE_SUCCESS);
    }

    @PutMapping("/update")
    public Response update(@RequestBody UserDto userDto) throws ValidationException {
        userDto.isValidForUpdate();
        this.userService.update(userDto);
        return new Response().success().message(CourseConstants.UPDATE_SUCCESS);
    }

    @GetMapping("/findById/{id}")
    public Response findById(@PathVariable("id") String id) {
        if (StringUtils.isEmpty(id)) {
            return new Response().fail().message(CourseConstants.REQUEST_PARAMS_ERROR);
        }
        UserDto userDto = this.userService.findById(id);
        return new Response()
                .success()
                .data(userDto)
                .message(CourseConstants.QUERY_SUCCESS);
    }

    /**
     * <h2>删除用户</h2>
     * @param id
     **/
    @DeleteMapping("/deleteById/{id}")
    public Response deleteById(@PathVariable("id") String id) {
        if (StringUtils.isEmpty(id)) {
            return new Response().fail().message(CourseConstants.REQUEST_PARAMS_ERROR);
        }
        this.userService.deleteById(id);
        return new Response().success().message(CourseConstants.DELETE_SUCCESS);
    }

    /**
     * <h2>重置密码</h2>
     * @param userDto
     **/
    @PostMapping("/resetPassword")
    public Response resetPassword(@RequestBody UserDto userDto) throws ValidationException {
        userDto.validForResetPassword();
        this.userService.resetPassword(userDto);
        return new Response().success().message(CourseConstants.RESET_PASSWORD_SUCCESS);
    }

    /**
     * <h2>登录</h2>
     * @param userDto
     **/
    @PostMapping("/login")
    public Response login(@RequestBody UserDto userDto) throws ValidationException {
        userDto.validForLogin();
        String imageCode = (String) redisTemplate.opsForValue().get(userDto.getImageCodeToken());
        redisTemplate.delete(userDto.getImageCodeToken());
        if (StringUtils.isEmpty(imageCode)) {
            log.info("用户登录失败");
            return new Response().fail().message(CourseConstants.IMAGECODE_EXPIRED);
        }
        if (!imageCode.toLowerCase().equals(userDto.getImageCode().toLowerCase())) {
            log.info("用户登录失败");
            return new Response().fail().message(CourseConstants.IMAGECODE_ERROR);
        }
        UserDto loginUser = this.userService.login(userDto);
        String token = UUID.randomUUID().toString();
        loginUser.setToken(token);
        redisTemplate.opsForValue().set(token, JSON.toJSONString(loginUser), 2 * 60 * 60, TimeUnit.SECONDS);
        return new Response().success().data(loginUser).message(CourseConstants.LOGIN_SUCCESS);
    }

    /**
     * <h2>退出登录</h2>
     * @param userDto
     **/
    @GetMapping("/logout/{token}")
    public Response logout(@PathVariable("token") String token) throws ValidationException {
        redisTemplate.delete(token);
        return new Response().success().message(CourseConstants.LOGOUT_SUCCESS);
    }

}
